package com.laolang.thresh;

import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.RandomUtil;
import com.google.common.collect.Maps;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.Jwts.SIG;
import io.jsonwebtoken.security.Keys;
import io.jsonwebtoken.security.SecureDigestAlgorithm;
import java.time.Instant;
import java.util.Date;
import java.util.Map;
import javax.crypto.SecretKey;
import lombok.extern.slf4j.Slf4j;
import org.testng.annotations.Test;

/**
 * jwt 测试.
 *
 * @author laolang
 * @version 0.1
 */
@Slf4j
public class JwtTest {

    /**
     * 过期时间: 60 秒
     */
    private static final int accessExpire = 60;

    /**
     * 加密算法
     */
    private final static SecureDigestAlgorithm<SecretKey, SecretKey> algorithm = SIG.HS256;

    /**
     * 私钥
     */
    private final static String secret = RandomUtil.randomString(32);

    /**
     * 秘钥
     */
    private static final SecretKey secretKey = Keys.hmacShaKeyFor(secret.getBytes());

    /**
     * jwt 签发者
     */
    private final static String jwtIss = "laolang";

    /**
     * jwt 主题
     */
    private final static String jwtSubject = "thresh";

    private final static Map<String, String> tokenMap = Maps.newHashMap();


    /**
     * 生成 jwt
     */
    @Test
    public void testGenJwt() {
        // 令牌 id
        String uuid = UUID.fastUUID().toString();
        // 到期时间
        Date expireDate = Date.from(Instant.now().plusSeconds(accessExpire));
        // payload
        Map<String, Object> claimsMap = Maps.newHashMap();
        claimsMap.put("id", 1001L);
        claimsMap.put("username", "laolang");

        String token = Jwts.builder()
            // 设置头部信息
            .header()
            .add("typ", "JWT")
            .add("alg", "HS256")
            .and()
            // payload
            .claims(claimsMap)
            // 令牌 id
            .id(uuid)
            // 过期时间
             .expiration(expireDate)
            // 签发时间
            .issuedAt(new Date())
            // 主题
            .subject(jwtSubject)
            // 签发者
            .issuer(jwtIss)
            // 签名
            .signWith(secretKey, algorithm)
            .compact();
        tokenMap.put("token", token);
        log.info(token);
    }

    /**
     * 解析 token
     */
    @Test
    public void testParseToken() {
        String token = tokenMap.get("token");
        try {
            Jws<Claims> claimsJws = Jwts.parser().verifyWith(secretKey).build()
                .parseSignedClaims(token);
            log.info("id:{}", claimsJws.getPayload().get("id", Integer.class));
            log.info("username:{}", claimsJws.getPayload().get("username", String.class));
        } catch (Exception e) {
            log.error("{}", e.getMessage());
        }
    }

}
